/*
 * Part of knowledge engineering (ke) course work, 2010/11
 */
package se.bth.ke.firstfriend.model;

import java.io.Serializable;
import java.util.Date;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.ManyToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

/**
 * Status of a todo, can be
 *  * new
 *  * viewed
 *  * done
 *  * deleted
 * See CheckPointState enum for details
 * 
 * @author markus.goetz, nico.rehwaldt
 */
@Entity
@DiscriminatorColumn(discriminatorType=DiscriminatorType.CHAR)
@DiscriminatorValue("b")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public class CheckPoint implements Serializable {
    
    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne
    private Todo todo;

    @Enumerated(EnumType.STRING)
    private State state = State.UNSPECIFIED;
    
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdAt;

    public CheckPoint() {
        this(State.UNSPECIFIED);
    }

    public CheckPoint(State state) {
        this.state = state;
        this.createdAt = new Date();
    }
    
    public CheckPoint(String state) {
        this(State.fromString(state));
    }

    public static CheckPoint viewed() {
        return new CheckPoint(State.VIEWED);
    }

    public static CheckPoint done() {
        return new CompletedCheckPoint();
    }

    public static CheckPoint deleted() {
        return new CheckPoint(State.DELETED);
    }

    public static CheckPoint workInProgress() {
        return new CheckPoint(State.WORK_IN_PROGRESS);
    }

    public Long getId() {
        return id;
    }

    /**
     * @param todo the todo to be set on the check point
     */
    public void setTodo(Todo todo) {
        this.todo = todo;
    }

    /**
     * Answers true if this check point has the specified state
     * 
     * @param state
     * @return
     */
    public boolean is(State state) {
        return (this.state == state);
    }

    @Override
    public String toString() {
        return "se.bth.ke.firstfriend.model.CheckPoint[id=" + id + ", state=" + state + "]";
    }

    public static enum State {

        WORK_IN_PROGRESS("work"),
        VIEWED("viewed"),
        DONE("done"),
        DELETED("deleted"),
        UNSPECIFIED("unspecified");

        private String stateString;

        private State(String stateString) {
            this.stateString = stateString;
        }

        public String getStateString() {
            return this.stateString;
        }

        public static State fromString(String stateString) {
            for (State state : State.values()) {
                if (state.getStateString().equals(stateString)) {
                    return state;
                }
            }
            throw new IllegalArgumentException("No such state available " + stateString);
        }
    }
}
